// OLD VERSION DO NOT USE
// Older pens still rely on this.

/**
 * MyMath.js
 * -----------
 * Handy math/trig reference.
 *
 * Author: Caleb Miller
 *         caleb@caleb-miller.com
 */

const MyMath = (function MyMathFactory(Math) {
  const MyMath = {}

  // degree/radian conversion constants
  MyMath.toDeg = 180 / Math.PI
  MyMath.toRad = Math.PI / 180
  MyMath.halfPI = Math.PI / 2
  MyMath.twoPI = Math.PI * 2

  // Pythagorean Theorem distance calculation
  MyMath.dist = (width, height) => {
    return Math.sqrt(width * width + height * height)
  }

  // Pythagorean Theorem point distance calculation
  // Same as above, but takes coordinates instead of dimensions.
  MyMath.pointDist = (x1, y1, x2, y2) => {
    const distX = x2 - x1
    const distY = y2 - y1
    return Math.sqrt(distX * distX + distY * distY)
  }

  // Returns the angle (in radians) of a 2D vector
  MyMath.angle = (width, height) => MyMath.halfPI + Math.atan2(height, width)

  // Returns the angle (in radians) between two points
  // Same as above, but takes coordinates instead of dimensions.
  MyMath.pointAngle = (x1, y1, x2, y2) =>
    MyMath.halfPI + Math.atan2(y2 - y1, x2 - x1)

  // Splits a speed vector into x and y components (angle needs to be in radians)
  MyMath.splitVector = (speed, angle) => ({
    x: Math.sin(angle) * speed,
    y: -Math.cos(angle) * speed
  })

  // Generates a random number between min (inclusive) and max (exclusive)
  MyMath.random = (min, max) => Math.random() * (max - min) + min

  // Generates a random integer between and possibly including min and max values
  MyMath.randomInt = (min, max) => ((Math.random() * (max - min + 1)) | 0) + min

  // Returns a random element from an array, or simply the set of provided arguments when called
  MyMath.randomChoice = function randomChoice(choices) {
    if (arguments.length === 1 && Array.isArray(choices)) {
      return choices[(Math.random() * choices.length) | 0]
    }
    return arguments[(Math.random() * arguments.length) | 0]
  }

  // Clamps a number between min and max values
  MyMath.clamp = function clamp(num, min, max) {
    return Math.min(Math.max(num, min), max)
  }

  return MyMath
})(Math)
